home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / maestro / source / displytl / xvxbm.c < prev   
Encoding:
C/C++ Source or Header  |  1993-06-15  |  5.5 KB  |  247 lines

  1. /*
  2.  * xvxbm.c - load routine for X11 Bitmap format pictures
  3.  *
  4.  * LoadXBM(fname)  -  loads an X11 Bitmap file\
  5.  * WriteXBM(fp, pic, w, h)
  6.  */
  7.  
  8. /*
  9.  * Copyright 1989, 1990, 1991, 1992 by John Bradley and
  10.  *                       The University of Pennsylvania
  11.  *
  12.  * Permission to use, copy, and distribute for non-commercial purposes,
  13.  * is hereby granted without fee, providing that the above copyright
  14.  * notice appear in all copies and that both the copyright notice and this
  15.  * permission notice appear in supporting documentation.
  16.  *
  17.  * The software may be modified for your own purposes, but modified versions
  18.  * may not be distributed.
  19.  *
  20.  * This software is provided "as is" without any expressed or implied warranty.
  21.  *
  22.  * The author may be contacted via:
  23.  *    US Mail:   John Bradley
  24.  *               GRASP Lab, Room 301C
  25.  *               3401 Walnut St.
  26.  *               Philadelphia, PA  19104
  27.  *
  28.  *    Phone:     (215) 898-8813
  29.  *    EMail:     bradley@cis.upenn.edu
  30.  */
  31.  
  32.  
  33. #include "xvimage.h"
  34.  
  35.  
  36.  
  37. /*
  38.  * File Format:
  39.  *   (format identifier:  "#define" as first couple chars in file)
  40.  *
  41.  * looks for first line beginning with '#define'
  42.  *   reads "#define identifier width"  (identifier is ignored)
  43.  * looks for next line beginning with '#define'
  44.  *   reads "#define identifier height" (identifier is ignored)
  45.  * looks for next occurence of characters '0x'
  46.  *   read next two chars as two hex digits
  47.  *   move forward to next occurence of '0x'
  48.  *   repeat
  49.  */
  50.  
  51.  
  52. static int XBMError();
  53.  
  54.  
  55. /*******************************************/
  56. int LoadXBM(fname,nc)
  57.      char *fname;
  58.      int   nc;
  59. /*******************************************/
  60. {
  61.   FILE  *fp;
  62.   int    c, c1;
  63.   int    i, j, k, bit, w, h;
  64.   byte  *pix;
  65.   long   filesize;
  66.   char   line[256];
  67.   byte   hex[256];
  68.  
  69.   k = 0;
  70.  
  71.   fp=fopen(fname,"r");
  72.   if (!fp) return 1;
  73.  
  74.   /* figure out the file size (for Informational Purposes Only) */
  75.   fseek(fp, 0L, 2);
  76.   filesize = ftell(fp);
  77.   fseek(fp, 0L, 0);
  78.  
  79.  
  80.   /* read width:  skip lines until we hit a #define */
  81.   while (1) {
  82.     if (!fgets(line,256,fp)) 
  83.       return(XBMError("EOF reached in header info."));
  84.  
  85.     if (strncmp(line,"#define",7)==0) {
  86.       if (sscanf(line,"#define %*s %d", &w) != 1) 
  87.     return(XBMError("Unable to read 'width'"));
  88.       else break;
  89.     }
  90.   }
  91.  
  92.  
  93.   /* read height:  skip lines until we hit another #define */
  94.   while (1) {
  95.     if (!fgets(line,256,fp)) 
  96.       return(XBMError("EOF reached in header info."));
  97.  
  98.     if (strncmp(line,"#define",7)==0) {
  99.       if (sscanf(line,"#define %*s %d", &h) != 1) 
  100.     return(XBMError("Unable to read 'height'"));
  101.       else break;
  102.     }
  103.   }
  104.  
  105.  
  106.  
  107.   /* scan forward until we see the first '0x' */
  108.   c = getc(fp);  c1 = getc(fp);
  109.   while (c1!=EOF && !(c=='0' && c1=='x') ) { c = c1;  c1 = getc(fp); }
  110.  
  111.   if (c1==EOF) 
  112.     return(XBMError("No bitmap data found"));
  113.  
  114.  
  115.   /* load up the stuff XV expects us to load up */
  116.  
  117.   sprintf(formatStr, "X11 Bitmap  (%ld bytes)", filesize);
  118.  
  119.   pic = (byte *) calloc(w*h,1);
  120.   if (!pic) FatalError("couldn't malloc 'pic'");
  121.  
  122.   pWIDE = w;  pHIGH = h;
  123.  
  124.   /* B/W bitmaps have a two entry colormap */
  125.   r[0] = g[0] = b[0] = 255;     /* 0 = white */
  126.   r[1] = g[1] = b[1] = 0;       /* 1 = black */
  127.  
  128.  
  129.   /* initialize the 'hex' array for zippy ASCII-hex -> int conversion */
  130.  
  131.   for (i=0; i<256; i++) hex[i]=0;
  132.   for (i='0'; i<='9'; i++) hex[i] = i - '0';
  133.   for (i='a'; i<='f'; i++) hex[i] = i + 10 - 'a';
  134.   for (i='A'; i<='F'; i++) hex[i] = i + 10 - 'A';
  135.  
  136.   /* read/convert the image data */
  137.  
  138.   for (i=0, pix=pic; i<h; i++)
  139.     for (j=0,bit=0; j<w; j++, pix++, bit = (++bit)&7) {
  140.  
  141.       if (!bit) {
  142.     /* get next byte from file.  we're already positioned at it */
  143.     c = getc(fp);  c1 = getc(fp);
  144.     if (c<0 || c1<0) { 
  145.       /* EOF: break out of loop */      
  146.       c=c1='0'; i=h; j=w;
  147.       XBMError("The file would appear to be truncated.");
  148.     }
  149.  
  150.     k = (hex[c] << 4) + hex[c1];
  151.  
  152.     /* advance to next '0x' */
  153.     c = getc(fp);  c1 = getc(fp);
  154.     while (c1!=EOF && !(c=='0' && c1=='x') ) { c = c1;  c1 = getc(fp); }
  155.       }
  156.  
  157.       *pix = (k&1) ? 1 : 0;
  158.       k = k >> 1;
  159.     }
  160.  
  161.   fclose(fp);
  162.  
  163.   return 0;
  164. }  
  165.  
  166.  
  167.  
  168. /*******************************************/
  169. static int XBMError(st)
  170. char *st;
  171. {
  172.   printf("%s\n",st);
  173.   return 1;
  174. }
  175.  
  176.  
  177. /*******************************************/
  178. int WriteXBM(fp, pic, w, h, fname)
  179. FILE *fp;
  180. byte *pic;
  181. int   w,h;
  182. char *fname;
  183. {
  184.   /* pic is expected to be an array of w*h bytes.  '0' is considered 'black'
  185.      non-zero is considered white.  Some sort of stippling algorithm should've
  186.      been called already to produce pic, otherwise the output won't be at all
  187.      useful */
  188.  
  189.   int   i,j,k,bit,len,nbytes;
  190.   byte *pix;
  191.   char name[256], *foo, *strchr();
  192.  
  193.   /* figure out a reasonable basename */
  194.   strcpy(name,fname);
  195.   foo = strchr(name,'.');
  196.   if (foo) *foo='\0';                 /* truncated name at first '.' */
  197.  
  198.   fprintf(fp,"#define %s_width %d\n",name,w);  
  199.   fprintf(fp,"#define %s_height %d\n",name,h);
  200.   fprintf(fp,"static char %s_bits[] = {\n",name);
  201.  
  202.   fprintf(fp," ");
  203.  
  204.   nbytes = h * ((w+7)/8);   /* # of bytes to write */
  205.  
  206.   for (i=0, len=1, pix=pic; i<h; i++) {
  207.     for (j=bit=k=0; j<w; j++,pix++) {
  208.       k = (k>>1);
  209.       if (*pix) k |= 0x80;
  210.       bit++;
  211.       if (bit==8) {
  212.     fprintf(fp,"0x%02x",(byte) ~k);
  213.     nbytes--;  len += 4;
  214.     if (nbytes) { fprintf(fp,",");  len++; }
  215.     if (len>72) { fprintf(fp,"\n ");  len=1; }
  216.     bit = k = 0;
  217.       }
  218.     }
  219.  
  220.     if (bit) {
  221.       k = k >> (8-bit);
  222.       fprintf(fp,"0x%02x",(byte) ~k);
  223.       nbytes--;  len += 4;
  224.       if (nbytes) { fprintf(fp,",");  len++; }
  225.       if (len>72) { fprintf(fp,"\n ");  len=1; }
  226.     }
  227.   }
  228.  
  229.   fprintf(fp,"};\n");
  230.  
  231.   if (ferror(fp)) return -1;
  232.   return 0;
  233. }
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.